package com.tools.service.user.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tools.common.enums.ResultCode;
import com.tools.common.exception.BusinessException;
import com.tools.mapper.user.UserMapper;
import com.tools.pojo.login.dto.LoginDTO;
import com.tools.pojo.login.vo.LoginVO;
import com.tools.pojo.user.bo.UpdateUserPwdBO;
import com.tools.pojo.user.bo.UserBO;
import com.tools.pojo.user.dto.UserDTO;
import com.tools.pojo.user.po.User;
import com.tools.pojo.user.vo.UserVO;
import com.tools.service.user.UserService;
import com.tools.utils.BeanUtils;
import com.tools.utils.MD5Util;
import io.micrometer.common.util.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public IPage<UserVO> page(UserDTO userDTO) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(userDTO.getUsername()), User::getUsername, userDTO.getUsername());
        wrapper.like(StringUtils.isNotBlank(userDTO.getNickname()), User::getNickname, userDTO.getNickname());
        wrapper.like(StringUtils.isNotBlank(userDTO.getEmail()), User::getEmail, userDTO.getEmail());
        wrapper.like(StringUtils.isNotBlank(userDTO.getPhoneNumber()), User::getPhoneNumber, userDTO.getPhoneNumber());
        wrapper.eq(StringUtils.isNotBlank(userDTO.getAccountStatus()), User::getAccountStatus, userDTO.getAccountStatus());
        wrapper.eq(StringUtils.isNotBlank(userDTO.getUsersRole()), User::getUsersRole, userDTO.getUsersRole());

        IPage<User> userPage = this.page(new Page<>(userDTO.getCurrent(), userDTO.getSize()), wrapper);

        return BeanUtils.convert(userPage, user -> BeanUtils.copyProperties(user, UserVO.class));
    }

    @Override
    public List<UserVO> list(UserDTO userDTO) {
        List<User> users = baseMapper.selectList(null);
        return BeanUtils.copyToList(users, UserVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveUser(UserBO userBO) {
        // 判断新增用户是否存在数据库中
        checkUserExist(userBO);
        // 不存在则新增
        User user = BeanUtils.copyProperties(userBO, User.class);
        // 密码加密
        user.setPassword(MD5Util.encrypt32("123456"));
        return save(user);
    }

    /**
     * 校验用户是否存在
     *
     * @param userBO 用户业务对象
     */
    private void checkUserExist(UserBO userBO) {
        // 账号 手机号 邮箱 不能重复
        if (userBO.getId() == null) {
            if (baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, userBO.getUsername())) != null) {
                throw new BusinessException(ResultCode.USERNAME_EXIST);
            }
        }
        if (baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhoneNumber, userBO.getPhoneNumber())) != null) {
            throw new BusinessException(ResultCode.PHONE_EXIST);
        }
        if (baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getEmail, userBO.getEmail())) != null) {
            throw new BusinessException(ResultCode.EMAIL_EXIST);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUser(UserBO userBO) {
        // 判断更新用户是否存在数据库中
        // 不存在则抛出异常
        if (getById(userBO.getId()) == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXIST);
        }
        // 存在则更新
//        checkUserExist(userBO);
        User user = BeanUtils.copyProperties(userBO, User.class);
        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(Long id) {
        User user = getById(id);
        user.setPassword(MD5Util.encrypt32("123456"));
        return updateById(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePassword(UpdateUserPwdBO updateUserPwdBO) {
        User user = getById(updateUserPwdBO.getId());
        if (!MD5Util.encrypt32(updateUserPwdBO.getOldPassword()).equals(user.getPassword())) {
            throw new BusinessException(ResultCode.OLD_PASSWORD_ERROR);
        }
        user.setPassword(MD5Util.encrypt32(updateUserPwdBO.getNewPassword()));
        return updateById(user);
    }

    @Override
    public User verifyUser(LoginDTO loginDTO) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, loginDTO.getUsername());
        User one = this.getOne(wrapper);
        if (one == null) {
            throw new BusinessException(ResultCode.LOGIN_ACCOUNT_NOT_REGISTER, "用户名不存在");
        }
        if (!MD5Util.encrypt32(loginDTO.getPassword()).equals(one.getPassword())) {
            throw new BusinessException(ResultCode.LOGIN_PASSWORD_ERROR, "密码错误");
        }
        return one;
    }

    @Override
    public UserVO getUserInfo() {
        // 获取当前登录用户
//        User user = StpUtil.getLoginUser().getUser();
        LoginVO loginVO = (LoginVO) StpUtil.getSession().get("userInfo");
        User user = loginVO.getUser();
        // 转换为VO
        return BeanUtils.copyProperties(user, UserVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteUsers(List<Long> ids) {
        return removeByIds(ids);
    }
}
